﻿package org.hsl.haxe;
/**
 * A signaler dispatches signals when the dispatcher calls the dispatch method. Dispatching means sending to the slot list, and
 * bubbling.
 */
interface ISignaler<D> {
	/**
	 * The methods defined in this object will not be used by the client in typical cases, and are therefor separated from the
	 * signaler itself.
	 */
	public var advanced(default, null):ISignalerAdvanced<D>;
	/**
	 * The target for any bubbling done by the signaler.
	 */
	public var bubblingTarget(default, setBubblingTarget):ISignaler<D>;
	/**
	 * The dispatcher that owns this signaler.
	 * 
	 * This property will be equal to the initialDispatcher property of the signals initially dispatched by the signaler
	 * (initially in this context means not in result of bubbling.)
	 */
	public var dispatcher(default, null):IDispatcher;
	/**
	 * Dispatches a signal. Dispatching means sending to the slot list, and bubbling.
	 * 
	 * The data property of the signal will equal the data that is passed to this method, while the initialDispatcher property
	 * will be equal to the dispatcher property of the signaler. If no data is specified, null will be used.
	 */
	public function dispatch(?data:D):Void;
	private function setBubblingTarget(value:ISignaler<D>):ISignaler<D>;
}
/**
 * The advanced API for signalers. The methods defined in this interface will not be used by the client in typical cases, and
 * are therefor separated from the ISignaler interface.
 */
interface ISignalerAdvanced<D> {
	/**
	 * Connects the signaler to a slot list. This method is usually called by the slot list.
	 */
	public function connectToSlotList(signalerSlotListBridge:ISignalerSlotListBridge<D>):Void;
	/**
	 * Disconnects the signaler from the slotlist it is currently connected to.
	 */
	public function disconnectFromSlotList():Void;
	/**
	 * Dispatches a signal that is currently in its bubbling process. Such signals were initially dispatched by a child of the
	 * dispatcher that owns the signaler. This method is usually called by the signaler of that child.
	 */
	public function dispatchBubbling(data:D, initialDispatcher:IDispatcher):Void;
}
/**
 * A null object implementation of the ISignaler interface.
 */
class NullSignaler<D> implements ISignaler<D> {
	public var advanced(default, null):ISignalerAdvanced<D>;
	public var bubblingTarget(default, setBubblingTarget):ISignaler<D>;
	public var dispatcher(default, null):IDispatcher;
	/**
	 * Creates a new null signaler.
	 */
	public function new():Void {
		advanced = new NullSignalerAdvanced<D>();
	}
	public function dispatch(?data:D):Void {
	}
	private function setBubblingTarget(value:ISignaler<D>):ISignaler<D> {
		return bubblingTarget = value;
	}
	private function toString():String {
		return "[ISignaler]";
	}
}
/**
 * A null object implementation of the ISignalerAdvanced interface.
 */
class NullSignalerAdvanced<D> implements ISignalerAdvanced<D> {
	/**
	 * Creates a new null signaler advanced.
	 */
	public function new():Void {
	}
	public function connectToSlotList(signalerSlotListBridge:ISignalerSlotListBridge<D>):Void {
	}
	public function disconnectFromSlotList():Void {
	}
	public function dispatchBubbling(data:D, initialDispatcher:IDispatcher):Void {
	}
	private function toString():String {
		return "[ISignalerAdvanced]";
	}
}